<?php

namespace App\Services;

use Illuminate\Support\Facades\Redis;

/**
 * Redis并发锁
 * Class RedisLockService
 * @package App\Services
 */
class RedisLockService
{
    private $key;
    private $expire;
    private $lockVal = '';

    public function __construct($key, $expire = 30)
    {
        $this->key = $key;
        $this->expire = $expire;
    }

    /**
     * 获取锁
     * @return bool
     */
    public function lock()
    {
        $val = uniqid();
        $result = Redis::set($this->key, $val, 'EX', $this->expire, 'NX');
        if($result){
            $this->lockVal = $val;
            return true;
        }
        return $result ? true : false;
    }

    /**
     * 阻塞获取锁
     * @return bool
     */
    public function lockLoop(){

        $sleepCount = 0;
        while (true){

            //超过20秒拿不到锁返回false
            if($sleepCount >= 20){
                return false;
            }

            $lock = $this->lock();
            if($lock){
                return true;
            }

            sleep(1);
            $sleepCount++;
        }

    }

    /**
     * 释放锁
     */
    public function unlock()
    {
        if($this->lockVal != ''){
            Redis::del($this->key);
        }
    }
}
